Summary: | [F03] system_clock with real-type count_rate does not compile | ||
---|---|---|---|
Product: | gcc | Reporter: | tobias.burnus |
Component: | fortran | Assignee: | Francois-Xavier Coudert <fxcoudert> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | fxcoudert, gcc-bugs, janus, jb, kargls |
Priority: | P3 | Keywords: | rejects-valid |
Version: | 4.2.0 | ||
Target Milestone: | 5.0 | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2007-05-29 20:44:46 | |
Bug Depends on: | |||
Bug Blocks: | 20585 | ||
Attachments: |
Idea how libgfortran/intrinsic/system_clock.c could look like
Revised idea how libgfortran/intrinsic/system_clock.c could look like |
Description
tobias.burnus
2006-07-25 17:09:10 UTC
gfortran is primarily a Fortran 95 with a few Fortran 2003 enhancements. Confirmed. Subject: Bug number PR28484 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-10/msg01387.html Assign. Preliminary patch at: http://gcc.gnu.org/ml/gcc-patches/2006-10/msg01387.html Created attachment 12535 [details] Idea how libgfortran/intrinsic/system_clock.c could look like Some bits of thought. Methods obtaining the time: * clock_gettime() [POSIX] 10^-9s (nanosecond) resolution, options: CLOCK_REALTIME - on unix time since the epoch [I would suggested this] CLOCK_MONOTONIC - survives even changing the time, but starting point is arbitrary See also PR 15516 for assembler calling sequences for Linux * gettimeofday (&tv, NULL) [POSIX] 10^-6s (microsecond) resolution * time() [POSIX] second resolution Resolution -> time able to be represented --------------------------------------------- For huge(i4) = 2147483647 1000 ms: 68 years 100 ms: 2485 days 10 ms: 246 days 1 ms: 25 days 100 us: 60 hours 10 us: 6 hours => 10 ms seems to be a good resolution, 25 days might be a bit short for some calculation jobs, but 250 days should be enough. For huge(i8) = 9223372036854775807 1 s: 2e11 years 1 ms: 2e8 years 1 us: 292271 years 1 ns: 292 years => 1 ns seems to be ok I'm thinking of the following library implementation: Only do integer(8) as this seems to be enough. (See attachment.) For iresolve.c one needs to do something like the following (pseudo code): if(count != NULL && counts.type != 8) gfc_convert_type() if(count != NULL && count_max.type != 8) gfc_convert_type() if(count != NULL && count_rate.type != 8) gfc_convert_type() c->resolved_sym = gfc_get_intrinsic_sub_symbol ("system_clock") if (count != NULL && count.type == 4) count = (int4) ((count8/10000000) % GFC_INTEGER_4_HUGE) else if (count != NULL && count.type != 8) count = (type) count8 if (count_rate != NULL && count_rate.type == 4) add_expression("if(count_rate8 == 0) count_rate = 0" "else count_rate = 100") else if (count != NULL && count.type != 8) count_rate = (type) count_rate8 if (count_max != NULL && count_max.type == 4) add_expression("if(count_max8 == 0) count_max = 0" "else count_max = GFC_INTEGER_4_HUGE") else if (count != NULL && count.type != 8) count_rate = (type) count_rate8 Created attachment 12536 [details]
Revised idea how libgfortran/intrinsic/system_clock.c could look like
The latter part is of cause not completely right if count_rate = 1 or 1000000, and for an error int16 and real counts didn't contain -huge().
Maybe having in the library a system_clock_4 version makes life easier.
The following pseudocode should then work with system_clock_4 and system_clock_8 (which has also the advantage that we don't modify the library which is nice in terms of compatibility :-)
if ( (counts != NULL && counts.type == 4)
||(count_max != NULL && count_max.type == 4) {
if(count != NULL && counts.type != 4)
gfc_convert_type()
if(count != NULL && count_max.type != 4)
gfc_convert_type()
if(count != NULL && count_rate.type != 4)
gfc_convert_type()
c->resolved_sym = gfc_get_intrinsic_sub_symbol ("system_clock_4")
if (counts != NULL && counts.type != 4)
add_expression("if(counts4 < 0) counts = -huge_max(type)"
"else counts = (type) counts4")
if (count_rate != NULL && count_rate.type != 4)
count_rate = (type) count_rate4
if (count_max != NULL && count_max.type != 4)
count_rate = (type) count_rate4
} else {
if(count != NULL && counts.type != 8)
gfc_convert_type()
if(count != NULL && count_max.type != 8)
gfc_convert_type()
if(count != NULL && count_rate.type != 8)
gfc_convert_type()
c->resolved_sym = gfc_get_intrinsic_sub_symbol ("system_clock_8")
if (counts != NULL && counts.type != 8)
add_expression("if(counts8 < 0) counts = -huge_max(type)"
"else counts = (type) counts8")
if (count_rate != NULL && count_rate.type != 8)
count_rate = (type) count_rate8
if (count_max != NULL && count_max.type != 8)
count_rate = (type) count_rate8
}
Now I only have to figure out how to add the conversion and the "if(counts8 < 0)" expression in iresolve.c.
Won't work on it for a while. Taking over. (In reply to comment #8) > Taking over. > Any news on this ? (In reply to comment #9) > Any news on this ? Bad ones. Lost track due to real-life interference. Unassigning myself for now. Raising this up a little since F2003 features are coming up Since the actual implementation of system_clock has no use for non-integer count rates, this should be implemented by creating an integer temporary in the frontend and then calling the existing functions. Also, note that as of r155359 the integer(8) version of system_clock now provides microsecond resolution. In the future, this could be improved further by switching to using clock_gettime(CLOCK_MONOTONIC,...) which in addition to providing better resolution also gives a monotonic clock instead of a realtime clock that gettimeofday() gives. Author: fxcoudert Date: Sun Jun 15 16:58:53 2014 New Revision: 211686 URL: https://gcc.gnu.org/viewcvs?rev=211686&root=gcc&view=rev Log: PR fortran/28484 PR fortran/61429 * check.c (gfc_check_system_clock): Improve checking of arguments. * intrinsic.texi: Update doc of SYSTEM_CLOCK. * iresolve.c (gfc_resolve_system_clock): Choose library function used depending on argument kinds. * trans-decl.c (gfc_build_intrinsic_function_decls): Build decls for system_clock_4 and system_clock_8. * trans-intrinsic.c (conv_intrinsic_system_clock): New function. (gfc_conv_intrinsic_subroutine): Call conv_intrinsic_system_clock. * trans.h (gfor_fndecl_system_clock4, gfor_fndecl_system_clock8): New variables. * gfortran.dg/system_clock_1.f90: New file. * gfortran.dg/system_clock_2.f90: New file. Added: trunk/gcc/testsuite/gfortran.dg/system_clock_1.f90 trunk/gcc/testsuite/gfortran.dg/system_clock_2.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/check.c trunk/gcc/fortran/intrinsic.texi trunk/gcc/fortran/iresolve.c trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-intrinsic.c trunk/gcc/fortran/trans.h trunk/gcc/testsuite/ChangeLog Fixed on trunk (4.10). |